package tbc.text1;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ServerMonitor {
    public void ServerMonitor(){
        Run();
    }

    /**
     * 用于执行服务器测试的任务
     */
    private static class ServerTester implements Callable<Boolean> {
        private String serverUrl;

        public ServerTester(String serverUrl) {
            this.serverUrl = serverUrl;
        }

        @Override
        public Boolean call() throws Exception {
            long startTime = System.currentTimeMillis(); // 记录开始时间

            boolean isServiceAvailable = checkServiceAvailability(serverUrl); // 检查服务器可用性
            if (isServiceAvailable) {
                System.out.println("服务 " + addProtocolPrefix(serverUrl) + ": 服务可用");
            } else {
                System.out.println("服务 " + addProtocolPrefix(serverUrl) + ": 服务不可用");
            }

            long endTime = System.currentTimeMillis(); // 记录结束时间
            long responseTime = endTime - startTime; // 计算响应时间
            System.out.println("响应时间：" + responseTime + " 毫秒");
            System.out.println("------------------------------------");

            return isServiceAvailable; // 返回服务器可用性结果
        }
    }

    public static void Run() {
        String serverFilePath = "resource/server.txt"; // 服务器URL文件的路径
        int phaseCount = 1; // 测试阶段计数

        ExecutorService executor = Executors.newFixedThreadPool(10); // 创建最多同时执行10个测试任务的线程池

        while (true) { // 不断进行测试循环
            System.out.println("============= 阶段 " + phaseCount++ + " 开始 =============");

            try (BufferedReader reader = new BufferedReader(new FileReader(serverFilePath))) { // 使用文件读取器读取服务器URL文件
                String serverUrl;
                int testCount = 0; // 每个阶段的测试计数

                while ((serverUrl = reader.readLine()) != null) { // 逐行读取服务器URL
                    ServerTester tester = new ServerTester(serverUrl); // 创建一个ServerTester对象来测试服务器
                    executor.submit(tester); // 提交测试任务到线程池进行异步执行
                    Thread.sleep(100);
                    testCount++; // 增加测试计数
                }

                executor.shutdown(); // 关闭线程池，不再接受新的任务
                try {
                    executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); // 等待所有任务执行完成
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("============= 阶段 " + (phaseCount - 1) + " 结束 =============");
                System.out.println("阶段总测试次数：" + testCount); // 打印本阶段的总测试次数
                System.out.println("");
                System.out.println("------------------------------------");
                System.out.println();

                try {
                    Thread.sleep(3000); // 等待3000毫秒（3秒）进入下一个测试阶段
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                executor = Executors.newFixedThreadPool(10); // 重置线程池，以备下一个测试阶段的使用
                reader.mark(0); // 标记文件的当前位置
                reader.reset(); // 将文件的位置重置到标记位置
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 检测服务器上的接收文件服务是否可用
     *
     * @param serverUrl 服务器URL
     * @return 返回true，如果服务可用；返回false，如果服务不可用
     */
    private static boolean checkServiceAvailability(String serverUrl) {
        String urlWithPrefix = addProtocolPrefix(serverUrl); // 给服务器URL添加协议前缀（如http://）

        try {
            URL url = new URL(urlWithPrefix); // 创建URL对象
            HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 打开连接
            connection.setRequestMethod("HEAD"); // 使用HEAD方法发送请求
            int responseCode = connection.getResponseCode(); // 获取响应码
            return (200 <= responseCode && responseCode <= 399); // 判断响应码是否在200到399之间，表示服务可用
        } catch (IOException e) {
            return false; // 发生异常时，返回false表示服务不可用
        }
    }

    /**
     * 添加协议前缀
     *
     * @param serverUrl 服务器URL
     * @return 返回带有协议前缀的URL
     */
    private static String addProtocolPrefix(String serverUrl) {
        if (!serverUrl.startsWith("http://") && !serverUrl.startsWith("https://")) {
            serverUrl = "http://" + serverUrl;
        }
        return serverUrl;
    }
}